#!/usr/bin/python

import cgi
import logging

from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

from hips import datastore
from hips import serialization
from hips.handlers import query


class ModelReadHandler(webapp.RequestHandler):
  """Base class for all handlers that process model IO requests."""

  def get(self):
    """Responds to requests for reading models from the store."""
    model_list = self.ReadModels(self.request)
    response_str = serialization.WriteModelListToString(model_list)
    logging.info("%s received read request, returning %s" %
        (self.__class__.__name__, response_str))
    self.response.out.write(response_str)

  def ReadModels(self, request_map):
    """Reads models from the request.
    
    Subclasses should implement this method. Basic model queries will return
    the result of a single call to self.QueryForModels. More advanced queries
    will query.Query and return multiple models.
    """
    pass


class InstitutionListHandler(ModelReadHandler):

  def ReadModels(self, request_map):
    # TODO Institution would normally have login context, but not for now
    # TODO Ordering
    return query.QueryForModels("SELECT * FROM Institution", request_map).All()


class DoctorListHandler(ModelReadHandler):

  def ReadModels(self, request_map):
    return query.QueryForModels("SELECT * FROM Doctor WHERE "
        "institution = :institution", request_map).All()


class ScheduleListHandler(ModelReadHandler):

  def ReadModels(self, request_map):
    return query.QueryForModels("SELECT * FROM Schedule WHERE "
        "institution = :institution", request_map).All()


class DoctorConstraintListHandler(ModelReadHandler):

  def ReadModels(self, request_map):
    return query.QueryForModels("SELECT * FROM DoctorConstraint WHERE "
        "schedule = :schedule", request_map).All()


class ScheduleSolutionListHandler(ModelReadHandler):

  def ReadModels(self, request_map):
    return query.QueryForModels("SELECT * FROM ScheduleSolution WHERE "
        "schedule = :schedule", request_map).All()


class InstitutionDetailsHandler(ModelReadHandler):

  def ReadModels(self, request_map):
    institution_key = db.Key(request_map.get("key"))
    institution_models = query.QueryForInstitution(institution_key)
    return institution_models.All()


class ScheduleDetailsHandler(ModelReadHandler):

  def ReadModels(self, request_map):
    schedule_key = db.Key(request_map.get("key"))
    schedule_models = query.QueryForSchedule(schedule_key)
    return schedule_models.All()


class ScheduleSolutionDetailsHandler(ModelReadHandler):

  def ReadModels(self, request_map):
    solution_key = db.Key(request_map.get("key"))
    models = query.QueryForScheduleSolution(solution_key)
    return models.All()
